home *** CD-ROM | disk | FTP | other *** search
- *
- * 6569.asm - VIC-Emulation
- *
- * Copyright (C) 1994-1995 by Christian Bauer
- *
-
- *
- * Anmerkungen:
- * ------------
- *
- * Funktionsweise/Periodic:
- * - Die VIC-Emulation arbeitet zeilenweise. Pro (simulierter)
- * C64-Rasterzeile wird vom 6510-Task die Routine Periodic6569
- * aufgerufen, die eine Pixelzeile der Grafik anhand der aktuellen
- * Einstellungen in den VIC-Registern aufbaut. Dadurch können
- * Rastereffekte sehr gut emuliert werden.
- * - Die Emulation schreibt die Grafikdaten für eine Rasterzeile in einen
- * 8-Bit-Chunky-Puffer, der in jeder Rasterzeile in die Anzeige kopiert
- * wird. Bei 4 Bit werden die Daten für ein ganzes Bild in den Puffer
- * kopiert, der dann im VIC-VBlank konvertiert wird.
- * - Die Auswahl der 5 verschiedenen Darstellungsmodi (plus 3 ungültige,
- * die einen schwarzen Bildschirm erzeugen) geschieht über den
- * Zeiger DisplayProc, der auf die entsprechende Routine (z.B. TextStd,
- * BitMapMulti etc.) zeigt und der bei einem Schreibzugriff auf eines
- * der beiden Kontrollregister CTRL1/CTRL2 neu gesetzt wird
- *
- * 6510-Zyklenzähler
- * - In jeder Rasterzeile wird der Zyklenzähler für die CPU neu gesetzt,
- * und zwar unterschiedlich je nachdem, ob eine Bad Line stattfand
- * oder nicht
- * - Für jedes dargestellte Sprite werden nochmal je 2 Zyklen abgezogen
- *
- * Bad Lines:
- * - Eine Bad Line ist dann, wenn $30 <= RASTER <= $f7 und
- * die unteren drei Bits von RASTER mit den unteren drei Bits von
- * Reg. $11 (Y-Scroll) übereinstimmen
- * - In einer Bad Line werden 40 Bytes aus Videomatrix und Farb-RAM geholt
- *
- * Rasterzähler RC/Grafikdarstellung:
- * - Der RC wird in jeder Bad Line auf Null gesetzt, gleichzeitig wird
- * die Darstellung der Grafik angeschaltet (DISPLAYOFF wird gelöscht)
- * - Am Ende einer Rasterzeile wird der RC um 1 erhöht, es sei denn,
- * er steht auf 7. In diesem Fall wird die Darstellung ausgeschaltet.
- * - Ist DISPLAYOFF gesetzt, wird in der Textspalte $3fff dargestellt,
- * ansonsten Text oder Bitmapgrafik
- * - Deshalb wird im oberen/unteren Rahmen immer $3fff dargestellt, weil
- * es dort keine Bad Lines gibt und der RC nie zurückgesetzt wird
- *
- * Videomatrixzähler VC:
- * - Es gibt zwei Register, VCBASE und VCCOUNT. Zum Zugriff auf die
- * Grafikdaten wird VCCOUNT benutzt.
- * - Beim VBlank wird VCBASE auf Null gesetzt
- * - Zu Beginn jeder Zeile wird VCCOUNT mit dem Wert aus VCBASE geladen
- * - Wenn DISPLAYOFF gelöscht ist und Grafik dargestellt wird, wird
- * VCCOUNT um 40 erhöht (symbolisch für die 40 Zugriffe des VIC)
- * - Wenn die Darstellung abgeschaltet wird, weil RC=7 ist (am Ende
- * einer Zeile) wird VCBASE mit dem Wert aus VCCOUNT geladen
- *
- * Spritedatenzähler MCx/Spritedarstellung:
- * - Da die Spritedaten beim VIC am Ende einer Rasterzeile geholt werden
- * und daher die Y-Positionen der Sprites eins niedriger als die
- * Rasterzeilennummern sind, werden die Spritedatenzähler in der
- * Emulation am Ende einer Rasterzeile gehandhabt (nachdem die Sprites
- * gezeichnet wurden)
- * - Wenn ein Sprite eingeschaltet ist und die Y-Koordinate gleich den
- * unteren 8 Bit von RASTER ist, wird der Datenzähler auf Null gesetzt
- * und die Darstellung des Sprite eingeschaltet (Bit in SPRITEON).
- * Jede folgende Rasterzeile wird der Zähler um 3 erhöht, solange er
- * kleiner als 60 ist. Erreicht er 60, wird die Darstellung des Sprite
- * ausgeschaltet. Wenn das Sprite Y-expandiert ist, wird der Zähler nur
- * in den Zeilen erhöht, in denen die unteren Bits von Y-Koordinate und
- * Zeilennummer gleich sind.
- * - Der Puffer GfxCollBuf wird beim Malen der Grafikdaten mit Flags
- * gefüllt, ob das zugehörige Pixel ein Vorder- oder Hintergrundpixel
- * ist. Dieser Puffer wird für die Sprite-Grafik-Kollisionserkennung
- * und für das Zeichnen von Hintergrundsprites benutzt.
- *
- * X-Scroll>0 und 40 Spalten:
- * - Wenn der X-Scroll>0 und die 40-Spalten-Darstellung eingeschaltet
- * ist, hängt das, was am linken Bildrand dargestellt wird, vom
- * aktuellen Grafikmodus ab
- * - Im Standard-Text-, Multicolor-Text- und Multicolor-Bitmap-Modus wird
- * dort die Hintergrundfarbe aus Reg.$21 dargestellt
- * - Im Standard-Bitmap- und ECM-Text-Modus wird die Hintergrundfarbe
- * der letzten 8 Pixel der vorherigen Zeile dargestellt
- *
- * Inkompatibilitäten:
- * - Effekte, die durch die Änderung von VIC-Registern innerhalb einer
- * Rasterzeile erreicht werden, können nicht emuliert werden
- * - Sprite-Kollisionen werden nur innerhalb des sichtbaren Bereiches
- * erkannt, Kollisionen mit $3fff werden gar nicht erkannt
- * - X-expandierte Sprites mit X-Koordinaten >=$140 werden nicht angezeigt.
- * Genaugenommen sollte ein Sprite nur dann unsichtbar sein, wenn die
- * X-Koordinate zwischen $1f8 und $1ff liegt.
- * - In den Bitmap-Darstellungen ab den Adressen $0000 und $8000 sollte
- * eigentlich ab $1000/$9000 das Char-ROM sichtbar sein. Aus
- * Geschwindigkeitsgründen wird in der Emulation das RAM darunter
- * dargestellt. Dies sollte keine Rolle spielen, da diese Bitmap-Seiten
- * aus dem genannten Grund von keinem Programm komplett verwendet werden.
- * - Der IRQ wird bei jedem Schreibzugriff in das Flag-Register gelöscht.
- * Das ist ein Hack für die RMW-Befehle des 6510, die zuerst den
- * Originalwert schreiben.
- * - Kein Lightpen-Interrupt
- *
-
- SPR_DATA_COLL SET 1 ;0 - Keine Sprite-Hintergrund-Prioritäten/-Kollisionen
-
- MACHINE 68020
-
- INCLUDE "exec/types.i"
- INCLUDE "exec/macros.i"
- INCLUDE "exec/nodes.i"
- INCLUDE "graphics/rastport.i"
- INCLUDE "libraries/cybergraphics.i"
-
- XREF _SysBase ;Main.asm
- XREF _GfxBase
- XREF _CyberGfxBase
-
- XREF TheRAM ;6510.asm
- XREF TheChar
- XREF TheColor
- XREF IntIsVICIRQ
- XREF CyclesLeft
-
- XREF CountTODs ;6526.asm
- XREF Periodic6526
-
- XREF _OpenDisplay ;Display.c
- XREF _RedrawDisplay
- XREF _the_rast_port
- XREF _temp_rp
-
- XDEF Init6569
- XDEF _GetVICDump
- XDEF OpenGraphics
- XDEF ChangedVA
- XDEF ReadFrom6569
- XDEF WriteTo6569
- XDEF Periodic6569
-
- XDEF DisplayID ;Prefs
- XDEF ScreenType
- XDEF NormalCycles
- XDEF BadLineCycles
- XDEF Collisions
- XDEF Overscan
- XDEF SkipLatch
- XDEF LimitSpeed
- XDEF DirectVideo
-
- SECTION "text",CODE
-
-
- **
- ** Definitionen
- **
-
- ; VIC-Register
- M0Y = $01 ;Y-Position von Sprite 0
- M1Y = $03 ;Y-Position von Sprite 1
- M2Y = $05 ;Y-Position von Sprite 2
- M3Y = $07 ;Y-Position von Sprite 3
- M4Y = $09 ;Y-Position von Sprite 4
- M5Y = $0b ;Y-Position von Sprite 5
- M6Y = $0d ;Y-Position von Sprite 6
- M7Y = $0f ;Y-Position von Sprite 7
- MX8 = $10 ;Höchste Bits der Sprite X-Positionen
- CTRL1 = $11 ;Steuerreg. 1
- RASTER = $12 ;Rasterzähler
- LPX = $13 ;Lightpen X
- LPY = $14 ;Lightpen Y
- SPREN = $15 ;Sprite eingeschaltet
- CTRL2 = $16 ;Steuerreg. 2
- MYE = $17 ;Sprite Y-Expansion
- VBASE = $18 ;Basisadressen
- IRQFLAG = $19 ;Interruptreg.
- IRQMASK = $1a
- MDP = $1b ;Sprite Priorität
- MMC = $1c ;Sprite Multicolor
- MXE = $1d ;Sprite X-Expansion
- CLXSPR = $1e ;Kollisionsreg.
- CLXBGR = $1f
- EC = $20 ;Rahmenfarbe
- B0C = $21 ;Hintergrundfarbe
-
- ; Zusätzliche Register
- DISPLAYOFF = $2f ;Flag: $3fff wird dargestellt
- IRQRASTER = $30 ;Rasterzeile, bei der ein IRQ ausgelöst wird (Wort)
- XSCROLL = $32 ;X-Scroll-Wert (Wort)
- YSCROLL = $34 ;Y-Scroll-Wert (Wort)
- DXSTART = $36 ;Aktuelle Werte des Randbereichs
- DXSTOP = $38
- DYSTART = $3a
- DYSTOP = $3c
- RC = $3e ;Rasterzähler RC
- MATRIXBASE = $40 ;Videomatrix-Basis (Amiga-Adresse)
- CHARBASE = $44 ;Zeichengenerator-Basis (Amiga-Adresse)
- BITMAPBASE = $48 ;Bitmap-Basis (Amiga-Adresse)
- CURRENTA5 = $4c ;Augenblicklicher Zeiger im ChunkyBuf
- ;Speicher für a5 zwischen Aufrufen von Periodic6569
- CURRENTRASTER = $50 ;Augenblickliche Rasterzeile
- ;Speicher für d7 zwischen Aufrufen von Periodic6569
- LASTBKGD = $52 ;Letzte dargestellte Hintergrundfarbe
- SPRITEON = $53 ;Sprite wird dargestellt, pro Sprite ein Bit
- BORDERON = $54 ;Flag: Oberer/unterer Rahmen wird dargestellt
- IS38COL = $55 ;Flag: 38 Spalten
- BADLINEENABLE = $56 ;Flag: Bad Lines sind zugelassen
- ;In Zeile $30 wird Bit 4 in $D011 getestet und
- ; dieses Flag entsprechend gesetzt
- SKIPFRAME = $57 ;Flag: Dieses Frame überspringen, nichts zeichnen
- BADLINE = $58 ;Flag: Bad-Line-Zustand
- MC0 = $5a ;Spritedatenzähler 0
- MC1 = $5c
- MC2 = $5e
- MC3 = $60
- MC4 = $62
- MC5 = $64
- MC6 = $66
- MC7 = $68 ;Spritedatenzähler 7
- VCBASE = $6a ;VC-Zwischenspeicher
- VCCOUNT = $6c ;VC-Zähler
- CIAVABASE = $6e ;16-Bit Basisadresse durch Cia-VA14/15
- BORDERLONG = $70 ;Vorberechnete Farbwerte
- BACK0LONG = $74
- SPRX0 = $78 ;16-Bit Sprite-X-Koordinaten
- SPRX1 = $7a
- SPRX2 = $7c
- SPRX3 = $7e
- SPRX4 = $80
- SPRX5 = $82
- SPRX6 = $84
- SPRX7 = $86
- SPR0BASE = $88
- SPR1BASE = $8a
- SPR2BASE = $8c
- SPR3BASE = $8e
- SPR4BASE = $90
- SPR5BASE = $92
- SPR6BASE = $94
- SPR7BASE = $96
- VICRegLength = $98
-
- ; Anzahl Rasterzeilen
- TotalRasters = $138
-
- ; Textfenster-Koordinaten (Stop-Werte sind immer eins mehr)
- Row25YStart = $33
- Row25YStop = $fb
- Row24YStart = $37
- Row24YStop = $f7
-
- Col40XStart = $20
- Col40XStop = $160
- Col38XStart = $27
- Col38XStop = $157
-
- ; Erste und letzte mögliche Zeile für Bad Lines
- FirstDMALine = $30
- LastDMALine = $f7
-
- ; Erste und letzte dargestellte Zeile
- FirstDispLine = $10
- LastDispLine = $11f ;eigentlich $12b
-
- ; Größe der Anzeige
- DisplayX = $180 ;Muß ein Vielfaches von 32 sein (wg. c2p4)!
- DisplayY = LastDispLine-FirstDispLine+1
-
- ; ScreenTypes
- STYP_8BIT = 0 ;8-Bit-Screen, WritePixelLine8/
- STYP_4BIT = 1 ;4-Bit-Screen, c2p4
- STYP_1BIT = 2 :1-Bit-Screen, Amiga Mono
-
- ; cybergraphics.library
- CYBRMATTR_ISLINEARMEM = $80000009
- GetCyberMapAttr = -96
- DoCDrawMethod = -156
-
-
- *
- * Makros
- *
-
- ; Sprite darstellen
- DoSprite MACRO ;Nummer
- btst #\1,SPRITEON(a4) ;Wird das Sprite dargestellt?
- beq \@1$
-
- move.l MATRIXBASE(a4),a0
- moveq #0,d0
- move.b $03f8+\1(a0),d0 ;Datenzeiger
- lsl.w #6,d0 ;*64
- add.w MC\1(a4),d0 ;MC dazunehmen
- bsr GetPhysical
- move.l (a0),d0 ;d0: Spritedaten
-
- move.w SPRX\1(a4),d1 ;d1: X-Koordinate
- move.l a5,a1
- add.w d1,a1
- addq.l #8,a1 ;a1: Ziel im Bildschirmspeicher
- lea SprCollBuf+8,a2
- add.w d1,a2 ;a2: Ziel im Kollisionspuffer
- IFNE SPR_DATA_COLL
- lea GfxCollBuf+8,a3
- add.w d1,a3 ;a3: Zeiger auf Grafik-Kollisionspuffer
- ENDC
-
- move.b $27+\1(a4),d2 ;d2: Spritefarbe
-
- move.b #1<<\1,d7 ;d7: Sprite-Bit
- jsr ([Sprite\1Proc])
- \@1$
- ENDM
-
-
- **
- ** Emulation vorbereiten
- **
-
- *
- * Register vorbereiten
- *
-
- Init6569 lea Registers,a0
- move.w #7,RC(a0)
- move.w #-1,CURRENTRASTER(a0)
- move.l TheRAM,MATRIXBASE(a0)
- move.l TheRAM,CHARBASE(a0)
- move.l TheRAM,BITMAPBASE(a0)
- clr.w CIAVABASE(a0)
- move.w #63,MC0(a0)
- move.w #63,MC1(a0)
- move.w #63,MC2(a0)
- move.w #63,MC3(a0)
- move.w #63,MC4(a0)
- move.w #63,MC5(a0)
- move.w #63,MC6(a0)
- move.w #63,MC7(a0)
-
- bsr SetDispProc
- bsr SetSpriteProcs
- rts
-
- *
- * Screen und Fenster öffnen
- * d0=0: Alles OK
- * d0=1: Konnte Screen nicht öffnen
- * d0=2: Kein Speicher
- *
-
- OpenGraphics pea DisplayY
- pea DisplayX
- moveq #0,d0
- move.w Overscan,d0
- move.l d0,-(sp)
- move.l DisplayID,-(sp)
- move.w ScreenType,d0
- move.l d0,-(sp)
- jsr _OpenDisplay
- lea 20(sp),sp
- tst.l d0
- bne 1$
-
- move.l _CURRENTA5,Registers+CURRENTA5
-
- move.l _CyberGfxBase,d0
- beq 2$
- move.l a6,-(sp)
- move.l d0,a6
-
- move.l _the_rast_port,a0 ;Ist es eine CyberGfx-Bitmap?
- move.l rp_BitMap(a0),a0
- move.l #CYBRMATTR_ISCYBERGFX,d0
- jsr GetCyberMapAttr(a6)
- tst.l d0
- beq 3$
-
- move.l _the_rast_port,a0 ;Ja, Direkter Zugriff erlaubt?
- move.l rp_BitMap(a0),a0
- move.l #CYBRMATTR_ISLINEARMEM,d0
- jsr GetCyberMapAttr(a6)
- tst.l d0
- beq 3$
- sne IsCyber ;Ja, DoCDrawMethod kann benutzt werden
-
- tst.w DirectVideo ;Zugriff ohne DoCDrawMethod gewünscht?
- beq 3$
-
- move.l _the_rast_port,a0 ;Ja, XMod und Basisadresse bestimmen
- move.l rp_BitMap(a0),a0
- move.l #CYBRMATTR_XMOD,d0
- jsr GetCyberMapAttr(a6)
- move.l d0,CyberXMod
-
- move.l _the_rast_port,a0
- move.l rp_BitMap(a0),a0
- move.l #CYBRMATTR_DISPADR,d0
- jsr GetCyberMapAttr(a6)
- move.l d0,CyberBase
- spl IsCyberDirect
- 3$
- move.l (sp)+,a6
- 2$
- moveq #0,d0
- 1$ rts
-
-
- **
- ** VIC-Status in Datenstruktur schreiben
- **
-
- _GetVICDump lea Registers,a0
- move.l 4(sp),a1
-
- move.b SPRX0+1(a0),(a1)+
- move.b M0Y(a0),(a1)+
- move.b SPRX1+1(a0),(a1)+
- move.b M1Y(a0),(a1)+
- move.b SPRX2+1(a0),(a1)+
- move.b M2Y(a0),(a1)+
- move.b SPRX3+1(a0),(a1)+
- move.b M3Y(a0),(a1)+
- move.b SPRX4+1(a0),(a1)+
- move.b M4Y(a0),(a1)+
- move.b SPRX5+1(a0),(a1)+
- move.b M5Y(a0),(a1)+
- move.b SPRX6+1(a0),(a1)+
- move.b M6Y(a0),(a1)+
- move.b SPRX7+1(a0),(a1)+
- move.b M7Y(a0),(a1)+
- move.b MX8(a0),(a1)+
-
- move.b CTRL1(a0),d0
- and.b #$7f,d0
- move.b CURRENTRASTER(a0),d1
- lsl.b #7,d1
- or.b d1,d0
- move.b d0,(a1)+
- move.b CURRENTRASTER+1(a0),(a1)+
-
- lea LPX(a0),a0
- moveq #27,d0 ;LPX..M7C
- 1$ move.b (a0)+,(a1)+
- dbra d0,1$
-
- lea Registers,a0
- addq.l #1,a1
- move.w IRQRASTER(a0),(a1)+
- move.w VCCOUNT(a0),(a1)+
- move.w VCBASE(a0),(a1)+
- move.b RC+1(a0),(a1)+
- move.b SPRITEON(a0),(a1)+
-
- move.b MC0+1(a0),(a1)+
- move.b MC1+1(a0),(a1)+
- move.b MC2+1(a0),(a1)+
- move.b MC3+1(a0),(a1)+
- move.b MC4+1(a0),(a1)+
- move.b MC5+1(a0),(a1)+
- move.b MC6+1(a0),(a1)+
- move.b MC7+1(a0),(a1)+
-
- tst.b DISPLAYOFF(a0)
- sne.b (a1)+
- sne.b (a1)+
- tst.b BADLINE(a0)
- sne.b (a1)+
- sne.b (a1)+
- tst.b BADLINEENABLE(a0)
- sne.b (a1)+
- sne.b (a1)+
- move.w CIAVABASE(a0),(a1)+
- move.w MATRIXBASE+2(a0),(a1)+
- move.w CHARBASE+2(a0),(a1)+
- move.w BITMAPBASE+2(a0),(a1)+
-
- move.l d2,-(sp)
- move.w CIAVABASE(a0),d2
- move.l MATRIXBASE(a0),a0
- moveq #7,d1
- lea $03f8(a0),a0
- 2$ moveq #0,d0
- move.b (a0)+,d0
- lsl.w #6,d0
- or.w d2,d0
- move.w d0,(a1)+
- dbra d1,2$
- move.l (sp)+,d2
- rts
-
-
- **
- ** CIA-VA14/15 hat sich geändert, Video-Bank wechseln
- ** d0.b: Neue VA ($00-$03)
- **
-
- ChangedVA lea Registers,a0 ;Wichtig für WrVBASE
- clr.w d1 ;VABase speichern
- move.b d0,d1
- ror.w #2,d1
- move.w d1,CIAVABASE(a0)
-
- move.b VBASE(a0),d1 ;Zeiger neu berechnen
- bra WrVBASE
-
-
- **
- ** Aus einer VIC-16-Bit-Adresse die entsprechende Amiga-Adresse berechnen
- ** -> d0.w: 16-Bit-Adresse
- ** <- a0.l: 32-Bit-Adresse
- **
-
- GetPhysical or.w CIAVABASE(a4),d0 ;VA14/15 dazunehmen
- move.w d0,d1
- and.w #$7000,d1
- cmp.w #$1000,d1
- beq 1$
- move.l TheRAM,a0
- moveq #0,d1
- move.w d0,d1
- add.l d1,a0
- rts
- 1$ and.w #$0fff,d0 ;$1000-$1fff, $9000-$9fff: Char-ROM
- move.l TheChar,a0
- add.w d0,a0
- rts
-
-
- **
- ** Aus einem VIC-Register lesen
- ** d0.l: Registernummer ($00-$3f)
- ** Rückgabe: d0.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- **
-
- ReadFrom6569 lea Registers,a0
- move.l ReadTab(pc,d0.l*4),a1
- jmp (a1)
-
- CNOP 0,4
- ReadTab dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
-
- dc.l RdNormal
- dc.l RdCTRL1
- dc.l RdRASTER
- dc.l RdNormal
- dc.l RdNormal
- dc.l RdNormal
- dc.l RdCTRL2
- dc.l RdNormal
- dc.l RdVBASE
- dc.l RdIRQFLAG
- dc.l RdIRQMASK
- dc.l RdNormal
- dc.l RdNormal
- dc.l RdNormal
- dc.l RdCLXSPR
- dc.l RdCLXBGR
-
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdUndef
-
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
-
- RdNormal move.b (a0,d0.l),d0
- rts
-
- RdSprX move.b SPRX0+1(a0,d0.l),d0 ;LSB lesen
- rts
-
- RdCTRL1 move.b CTRL1(a0),d0
- and.b #$7f,d0
- move.b CURRENTRASTER(a0),d1 ;MSB des Rasterzählers lesen
- lsl.b #7,d1
- or.b d1,d0 ;und dazunehmen
- rts
-
- RdRASTER move.b CURRENTRASTER+1(a0),d0 ;Rasterzähler lesen
- rts
-
- RdCTRL2 move.b CTRL2(a0),d0
- or.b #$c0,d0 ;Unbenutzte Bits auf 1
- rts
-
- RdVBASE move.b VBASE(a0),d0
- or.b #$01,d0 ;Unbenutzte Bits auf 1
- rts
-
- RdIRQFLAG move.b IRQFLAG(a0),d0
- or.b #$70,d0 ;Unbenutzte Bits auf 1
- rts
-
- RdIRQMASK move.b IRQMASK(a0),d0
- or.b #$f0,d0 ;Unbenutzte Bits auf 1
- rts
-
- RdCLXSPR lea CLXSPR(a0),a0
- move.b (a0),d0 ;Lesen und löschen
- clr.b (a0)
- rts
-
- RdCLXBGR lea CLXBGR(a0),a0
- move.b (a0),d0 ;Lesen und löschen
- clr.b (a0)
- rts
-
- RdColor move.b (a0,d0.l),d0 ;Bei den Farbregistern
- or.b #$f0,d0 ;das obere Nibble setzen
- rts
-
- RdUndef st.b d0 ;Nicht existierendes Register
- rts
-
-
- **
- ** In ein VIC-Register schreiben
- ** d0.l: Registernummer ($00-$3f)
- ** d1.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- **
-
- WriteTo6569 lea Registers,a0
- move.l WriteTab(pc,d0.l*4),a1
- jmp (a1)
-
- CNOP 0,4
- WriteTab dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
-
- dc.l WrSprXMSB
- dc.l WrCTRL1
- dc.l WrRASTER
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrCTRL2
- dc.l WrNormal
- dc.l WrVBASE
- dc.l WrIRQFLAG
- dc.l WrIRQMASK
- dc.l WrMDP
- dc.l WrMMC
- dc.l WrMXE
- dc.l WrUndef
- dc.l WrUndef
-
- dc.l WrBorder
- dc.l WrBack0
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrUndef
-
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
-
- WrNormal move.b d1,(a0,d0.l)
- WrUndef rts
-
- WrSprX move.b d1,SPRX0+1(a0,d0.l)
- rts
-
- WrSprXMSB move.b d1,MX8(a0)
- lea SPRX7(a0),a0 ;MSBs in 16-Bit-Werte umrechnen
- moveq #7,d0
- 1$ add.b d1,d1
- bcs 2$
- clr.b (a0)
- bra 3$
- 2$ move.b #1,(a0)
- 3$ subq.w #2,a0
- dbra d0,1$
- rts
-
- WrCTRL1 move.b d1,CTRL1(a0)
-
- move.b d1,d0 ;Y-Scroll
- and.w #7,d0
- move.w d0,YSCROLL(a0)
-
- move.b d1,d0 ;MSB der IRQ-Rasterzeile
- lsr.b #7,d0
- move.b d0,IRQRASTER(a0)
-
- btst #3,d1 ;24/25 Zeilen
- beq 1$
- move.w #Row25YStart,DYSTART(a0)
- move.w #Row25YStop,DYSTOP(a0)
- bra SetDispProc
- 1$ move.w #Row24YStart,DYSTART(a0)
- move.w #Row24YStop,DYSTOP(a0)
- bra SetDispProc
-
- SetDispProc moveq #0,d0 ;ECM, BMM und MCM holen
- move.b CTRL1(a0),d0
- and.b #$60,d0
- move.b CTRL2(a0),d1
- and.b #$10,d1
- or.b d1,d0
- lsr.b #2,d0 ;Als Index in DispProcTab benutzen
- cmp.w #STYP_1BIT,ScreenType
- beq 1$
- move.l (DispProcTab,pc,d0.l),DisplayProc
- rts
- 1$ move.l (MonoDispProcTab,pc,d0.l),DisplayProc
- rts
-
- WrRASTER move.b d1,IRQRASTER+1(a0)
- rts
-
- WrCTRL2 move.b d1,CTRL2(a0)
-
- move.b d1,d0 ;X-Scroll
- and.w #7,d0
- move.w d0,XSCROLL(a0)
-
- btst #3,d1 ;38/40 Zeilen
- seq.b IS38COL(a0)
- beq 1$
- move.w #Col40XStart,DXSTART(a0)
- move.w #Col40XStop,DXSTOP(a0)
- bra SetDispProc
- 1$ move.w #Col38XStart,DXSTART(a0)
- move.w #Col38XStop,DXSTOP(a0)
- bra SetDispProc
-
- WrVBASE move.l a0,a1 ;a1: Zeiger auf Register
- move.b d1,VBASE(a1)
-
- move.l a4,-(sp)
- move.l a1,a4 ;Für GetPhysical
-
- move.w d1,-(sp)
- move.b d1,d0 ;Videomatrixbasis berechnen
- and.w #$f0,d0
- lsl.w #6,d0
- bsr GetPhysical
- move.l a0,MATRIXBASE(a1)
- move.w (sp),d1 ;Nur lesen, nicht entfernen
-
- move.b d1,d0 ;Zeichengeneratorbasis berechnen
- and.w #$0e,d0
- ror.w #6,d0
- bsr GetPhysical
- move.l a0,CHARBASE(a1)
- move.w (sp)+,d1
-
- move.b d1,d0
- and.w #$08,d0
- ror.w #6,d0
- bsr GetPhysical
- move.l a0,BITMAPBASE(a1)
-
- move.l (sp)+,a4
- rts
-
- WrIRQFLAG not.b d1 ;Gesetztes Bit: Flag löschen
- and.b #$0f,d1
- move.b IRQFLAG(a0),d0
- and.b d1,d0
-
- clr.b IntIsVICIRQ ;IRQ zurücknehmen (Hack!)
-
- move.b d0,d1 ;Erlaubter IRQ noch gesetzt?
- and.b IRQMASK(a0),d1
- beq 1$
- or.b #$80,d0 ;Ja, Master-Bit setzen
- 1$ move.b d0,IRQFLAG(a0)
- rts
-
- WrIRQMASK and.b #$0f,d1
- move.b d1,IRQMASK(a0)
- ;!! Evtl. IRQ auslösen
- rts
-
- WrMDP move.b d1,MDP(a0)
- bra SetSpriteProcs
-
- WrMMC move.b d1,MMC(a0)
- bra SetSpriteProcs
-
- WrMXE move.b d1,MXE(a0) ;Fällt durch!
-
- SetSpriteProcs moveq #7,d1
- lea Sprite7Proc,a1
- 1$ moveq #0,d0
- btst d1,MXE(a0)
- beq 2$
- or.b #1,d0
- 2$ btst d1,MMC(a0)
- beq 3$
- or.b #2,d0
- 3$ btst d1,MDP(a0)
- beq 4$
- or.b #4,d0
- 4$ move.l (SpriteProcTab,pc,d0.l*4),(a1)
- subq.w #4,a1
- dbra d1,1$
- rts
-
- WrBorder move.b d1,EC(a0)
- move.b d1,d0 ;In ein Langwort konvertieren
- lsl.w #8,d0
- move.b d1,d0
- move.w d0,d1
- swap d0
- move.w d1,d0
- move.l d0,BORDERLONG(a0)
- moveq #0,d0
- rts
-
- WrBack0 move.b d1,B0C(a0)
- move.b d1,d0 ;In ein Langwort konvertieren
- lsl.w #8,d0
- move.b d1,d0
- move.w d0,d1
- swap d0
- move.w d1,d0
- move.l d0,BACK0LONG(a0)
- moveq #0,d0
- rts
-
-
- **
- ** Eine Rasterzeile des VIC ausführen
- **
- ** d7: Rasterzeilenzähler
- ** a4: Zeiger auf VIC-Register
- ** a5: Zeiger auf das Ziel im Bildschirmspeicher
- **
-
- ; VBlank: Zähler zurücksetzen
- VICVBlank move.w #-1,CURRENTRASTER(a4)
- clr.w VCBASE(a4)
-
- bsr CountTODs ;TODs zählen
-
- subq.w #1,SkipCounter
- sne SKIPFRAME(a4)
- bne Periodic6569
- move.w SkipLatch,SkipCounter
-
- ; Grafik darstellen
- jsr _RedrawDisplay
- move.l _CURRENTA5,CURRENTA5(a4)
-
- ; CyberDirect: Basisadresse des Bildschirmspeichers holen
- tst.b IsCyberDirect
- beq 1$
- move.l _CyberGfxBase,a6
- move.l _the_rast_port,a0
- move.l rp_BitMap(a0),a0
- move.l #CYBRMATTR_DISPADR,d0
- jsr GetCyberMapAttr(a6)
- move.l d0,CyberBase
- 1$
- ;fällt durch!
-
- *
- * Aktuelle Rasterzeile holen
- *
-
- Periodic6569 lea Registers,a4
- move.w CURRENTRASTER(a4),d7
-
- *
- * Rasterzähler erhöhen (muß hier geschehen, damit bei einem Raster-IRQ
- * der Wert des Rasterzählers mit der IRQ-Zeile übereinstimmt)
- *
-
- addq.w #1,d7
- move.w d7,CURRENTRASTER(a4)
- cmp.w #TotalRasters,d7 ;Bildende erreicht?
- beq VICVBlank
-
- *
- * Raster-IRQ auslösen, wenn Vergeichswert erreicht
- *
-
- cmp.w IRQRASTER(a4),d7 ;IRQ-Zeile erreicht?
- bne NoRasterIRQ
- or.b #$01,IRQFLAG(a4) ;Ja, IRST-Bit setzen
- btst #0,IRQMASK(a4) ;Raster-IRQ erlaubt?
- beq NoRasterIRQ
- or.b #$80,IRQFLAG(a4) ;Ja, IRQ-Bit setzen
- st.b IntIsVICIRQ ;Und Interrupt auslösen
- NoRasterIRQ
-
- *
- * In Zeile $30 entscheidet das DEN-Bit, ob Bad Lines auftreten dürfen
- *
-
- cmp.w #$30,d7
- bne 1$
- btst #4,CTRL1(a4)
- sne BADLINEENABLE(a4)
- 1$
-
- *
- * Neue Anzahl CPU-Zyklen setzen
- *
-
- move.w NormalCycles,CyclesLeft
-
- tst.b SKIPFRAME(a4)
- bne VICSkip
-
- *
- * Innerhalb des sichtbaren Bereichs?
- *
-
- cmp.w #FirstDispLine,d7
- blo VICNop
- cmp.w #LastDispLine,d7
- bhi VICNop
-
- *
- * Zeiger in Bildschirmspeicher nach a5 holen
- *
-
- move.l CURRENTA5(a4),a5
-
- *
- * VC-Zähler setzen
- *
-
- move.w VCBASE(a4),VCCOUNT(a4)
- clr.b BADLINE(a4)
-
- *
- * Bei Amiga-Mono in Mono-VIC-Routine verzweigen
- *
-
- cmp.w #STYP_1BIT,ScreenType
- beq AmigaMono6569
-
- *
- * "Bad Lines"-Videomatrixzugriff:
- * 40 Bytes aus Videomatrix und Farb-RAM lesen und zwischenspeichern
- *
-
- tst.b BADLINEENABLE(a4) ;War das DEN-Bit in Rasterzeile $30 gesetzt?
- beq NoBadLine
-
- cmp.w #FirstDMALine,d7 ;Innerhalb des DMA-Bereiches?
- blo NoBadLine
- cmp.w #LastDMALine,d7
- bhi NoBadLine
-
- move.b d7,d0 ;Ja, stimmen die unteren Bits
- and.b #7,d0 ;der Rasterzeile mit dem Y-Scroll
- cmp.b YSCROLL+1(a4),d0 ;überein?
- bne NoBadLine
-
- IsBadLine st.b BADLINE(a4) ;Ja, Bad Line
- move.w VCCOUNT(a4),d2 ;d2: VC Videomatrix-Zähler
-
- move.l MATRIXBASE(a4),a0 ;Videomatrixbasis holen
- add.w d2,a0 ;Videomatrixzähler dazunehmen
-
- move.l TheColor,a2 ;Zeiger auf Farb-RAM holen
- add.w d2,a2 ;Videomatrixzähler dazunehmen
-
- lea MatrixLine,a1 ;Videomatrix- und Farb-RAM-Zeile lesen
- lea ColorLine,a3
- movem.l (a0)+,d0-d6 ;Je 40 Bytes kopieren
- movem.l d0-d6,(a1)
- movem.l (a2)+,d0-d6
- movem.l d0-d6,(a3)
- movem.l (a0)+,d0-d2
- movem.l d0-d2,28(a1)
- movem.l (a2)+,d0-d2
- movem.l d0-d2,28(a3)
-
- clr.w RC(a4) ;RC zurücksetzen
- clr.b DISPLAYOFF(a4) ;Darstellung anschalten
-
- move.w BadLineCycles,CyclesLeft ;Andere Anzahl Zyklen
- NoBadLine
-
- *
- * Oberen und unteren Rahmen handhaben
- *
-
- cmp.w DYSTOP(a4),d7 ;Unteres Ende des Fensters erreicht?
- bne 1$ ; -> Rahmen einschalten
- st.b BORDERON(a4)
- bra TBBorderDraw
-
- 1$ btst #4,CTRL1(a4) ;Rahmen nur abschalten, wenn DEN-Bit gesetzt
- beq TBBorderDone
- cmp.w DYSTART(a4),d7 ;Oberes Ende des Fensters erreicht?
- bne TBBorderDone ; -> Rahmen abschalten
- clr.b BORDERON(a4)
- bra TBNoBorder
-
- TBBorderDone tst.b BORDERON(a4) ;Rahmen an?
- beq TBNoBorder
-
- TBBorderDraw move.l a5,a0 ;Ja, Rahmen malen.
- move.l BORDERLONG(a4),d0 ;d0.l: Rahmenfarbe
- moveq #DisplayX/4-1,d1
- 1$ move.l d0,(a0)+
- dbra d1,1$
- bra VICIncA5 ;Sonst nix
- TBNoBorder
-
- *
- * Inhalt des Fensters: Darstellung eingeschaltet?
- *
-
- lea Col40XStart(a5),a1
- add.w XSCROLL(a4),a1 ;a1: Ziel in Bildschirmspeicher
- lea MatrixLine,a2 ;a2: Zeichencodes
- lea ColorLine,a3 ;a3: Farbcodes
- IFNE SPR_DATA_COLL
- lea GfxCollBuf+Col40XStart,a6
- add.w XSCROLL(a4),a6 ;a6: Grafik-Kollisionspuffer
- ENDC
-
- tst.b DISPLAYOFF(a4) ;$3FFF darstellen?
- bne Show3FFF
-
- jmp ([DisplayProc]) ;Nein, Routine für entsp. Modus anspringen
-
- *
- * Standard-Text: Zeichendaten holen und darstellen
- *
-
- TextStd add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
-
- move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
- add.w RC(a4),a0 ;RC dazunehmen
-
- move.l BACK0LONG(a4),d3 ;d3.l: Hintergrundfarbe
-
- move.l d3,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
- move.l d3,Col40XStart+4(a5)
-
- ; Schleife für 40 Zeichen
- moveq #39,d1 ;d1: Zeichenzähler
- moveq #0,d0
- CharLoop move.b (a2)+,d0 ;Zeichencode lesen
- move.b (a0,d0.l*8),d0 ;Zeichendaten lesen
- beq OnlyBack
- move.b (a3)+,d2 ;d2: Zeichenfarbe
-
- ; 8 Pixel konvertieren
- add.b d0,d0
- bcc 11$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 12$
- 11$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 12$ add.b d0,d0
- bcc 21$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 22$
- 21$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 22$ add.b d0,d0
- bcc 31$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 32$
- 31$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 32$ add.b d0,d0
- bcc 41$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 42$
- 41$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 42$ add.b d0,d0
- bcc 51$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 52$
- 51$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 52$ add.b d0,d0
- bcc 61$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 62$
- 61$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 62$ add.b d0,d0
- bcc 71$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 72$
- 71$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 72$ add.b d0,d0
- bcc 81$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 82$
- 81$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 82$ dbra d1,CharLoop
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- OnlyBack move.l d3,(a1)+
- move.l d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.l (a6)+
- clr.l (a6)+
- ENDC
- addq.w #1,a3 ;Farb-RAM-Byte überspringen
- dbra d1,CharLoop
- bra DoSprites
-
- *
- * Multicolor-Text: Zeichendaten holen und darstellen
- *
-
- TextMulti add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
-
- move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
- add.w RC(a4),a0 ;RC dazunehmen
-
- move.l BACK0LONG(a4),d3 ;d3.l: Farbe 0
-
- move.w $22(a4),d4 ;d4.w: Farbe 1
- move.b $22(a4),d4
-
- move.w $23(a4),d5 ;d5.w: Farbe 2
- move.b $23(a4),d5
-
- move.l d3,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
- move.l d3,Col40XStart+4(a5)
-
- ; Schleife für 40 Zeichen
- moveq #39,d1 ;d1: Zeichenzähler
- moveq #0,d0
- CharMLoop move.b (a2)+,d0 ;Zeichencode lesen
- move.b (a0,d0.l*8),d0 ;Zeichendaten lesen
- beq MOnlyBack
- move.b (a3)+,d2 ;d2: Farbnibble
- bclr #3,d2 ;Standard oder Multi?
- beq StdInMulti
-
- ; Multicolor: 4 Pixel konvertieren
- add.b d0,d0
- bcc 11$
- add.b d0,d0
- bcc 12$
- move.b d2,(a1)+ ;11
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 14$
- 12$ move.w d5,(a1)+ ;10
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 14$
- 11$
- IFNE SPR_DATA_COLL
- clr.w (a6)+
- ENDC
- add.b d0,d0
- bcc 13$
- move.w d4,(a1)+ ;01
- bra 14$
- 13$ move.w d3,(a1)+ ;00
- 14$
-
- add.b d0,d0
- bcc 21$
- add.b d0,d0
- bcc 22$
- move.b d2,(a1)+ ;11
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 24$
- 22$ move.w d5,(a1)+ ;10
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 24$
- 21$
- IFNE SPR_DATA_COLL
- clr.w (a6)+
- ENDC
- add.b d0,d0
- bcc 23$
- move.w d4,(a1)+ ;01
- bra 24$
- 23$ move.w d3,(a1)+ ;00
- 24$
-
- add.b d0,d0
- bcc 31$
- add.b d0,d0
- bcc 32$
- move.b d2,(a1)+ ;11
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 34$
- 32$ move.w d5,(a1)+ ;10
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 34$
- 31$
- IFNE SPR_DATA_COLL
- clr.w (a6)+
- ENDC
- add.b d0,d0
- bcc 33$
- move.w d4,(a1)+ ;01
- bra 34$
- 33$ move.w d3,(a1)+ ;00
- 34$
-
- add.b d0,d0
- bcc 41$
- add.b d0,d0
- bcc 42$
- move.b d2,(a1)+ ;11
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 44$
- 42$ move.w d5,(a1)+ ;10
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 44$
- 41$
- IFNE SPR_DATA_COLL
- clr.w (a6)+
- ENDC
- add.b d0,d0
- bcc 43$
- move.w d4,(a1)+ ;01
- bra 44$
- 43$ move.w d3,(a1)+ ;00
- 44$
- dbra d1,CharMLoop
- bra DoSprites
-
- ; Standard: 8 Pixel konvertieren
- CNOP 0,4
- StdInMulti add.b d0,d0
- bcc 11$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 12$
- 11$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 12$ add.b d0,d0
- bcc 21$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 22$
- 21$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 22$ add.b d0,d0
- bcc 31$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 32$
- 31$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 32$ add.b d0,d0
- bcc 41$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 42$
- 41$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 42$ add.b d0,d0
- bcc 51$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 52$
- 51$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 52$ add.b d0,d0
- bcc 61$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 62$
- 61$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 62$ add.b d0,d0
- bcc 71$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 72$
- 71$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 72$ add.b d0,d0
- bcc 81$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 82$
- 81$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 82$ dbra d1,CharMLoop
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- MOnlyBack move.l d3,(a1)+
- move.l d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.l (a6)+
- clr.l (a6)+
- ENDC
- addq.w #1,a3 ;Farb-RAM-Byte überspringen
- dbra d1,CharMLoop
- bra DoSprites
-
- *
- * Extended Color Mode: Grafikdaten holen und darstellen
- *
-
- TextECM add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
-
- move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
- add.w RC(a4),a0 ;RC dazunehmen
-
- move.b $21(a4),d3 ;d3: Hintergrund 0
- move.b $22(a4),d4 ;d4: Hintergrund 1
- move.b $23(a4),d5 ;d5: Hintergrund 2
-
- move.w LASTBKGD(a4),d0 ;Letzter Hintergrund, wenn X-Scroll>0
- move.b LASTBKGD(a4),d0
-
- move.w d0,Col40XStart(a5)
- move.w d0,Col40XStart+2(a5)
- move.w d0,Col40XStart+4(a5)
- move.w d0,Col40XStart+6(a5)
-
- ; Schleife für 40 Zeichen
- ; d7: Aktuelle Hintergrundfarbe
- moveq #39,d1 ;d1: Zeichenzähler
- moveq #0,d0
- CharELoop move.b (a2)+,d0 ;Zeichencode lesen
- move.b (a3)+,d2 ;d2: Farbnibble
- bclr #7,d0
- bne 1$
- bclr #6,d0
- bne 2$
- move.b d3,d7 ;00: Hintergrund 0
- bra 4$
- 2$ move.b d4,d7 ;01: Hintergrund 1
- bra 4$
- 1$ bclr #6,d0
- bne 3$
- move.b d5,d7 ;10: Hintergrund 2
- bra 4$
- 3$ move.b $24(a4),d7 ;11: Hintergrund 3
- 4$ move.b (a0,d0.l*8),d0 ;Zeichendaten lesen
- beq EOnlyBack
-
- ; 8 Pixel konvertieren
- add.b d0,d0
- bcc 11$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 12$
- 11$ move.b d7,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 12$ add.b d0,d0
- bcc 21$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 22$
- 21$ move.b d7,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 22$ add.b d0,d0
- bcc 31$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 32$
- 31$ move.b d7,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 32$ add.b d0,d0
- bcc 41$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 42$
- 41$ move.b d7,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 42$ add.b d0,d0
- bcc 51$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 52$
- 51$ move.b d7,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 52$ add.b d0,d0
- bcc 61$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 62$
- 61$ move.b d7,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 62$ add.b d0,d0
- bcc 71$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 72$
- 71$ move.b d7,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 72$ add.b d0,d0
- bcc 81$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 82$
- 81$ move.b d7,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 82$ dbra d1,CharELoop
-
- move.b d7,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
- move.w CURRENTRASTER(a4),d7 ;d7 wurde zerstört
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- EOnlyBack move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- IFNE SPR_DATA_COLL
- clr.l (a6)+
- clr.l (a6)+
- ENDC
- dbra d1,CharELoop
- move.b d7,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
- move.w CURRENTRASTER(a4),d7 ;d7 wurde zerstört
- bra DoSprites
-
- *
- * Standard-BitMap: Grafikdaten holen und darstellen
- *
-
- BitMapStd move.l BITMAPBASE(a4),a0 ;a0: Bitmap-Basis
- move.w VCCOUNT(a4),d0 ;VC holen
- lsl.w #3,d0 ;*8
- add.w RC(a4),d0 ;RC dazunehmen
- add.w d0,a0 ;und zur Bitmap-Basis dazunehmen
-
- add.w #40,VCCOUNT(a4) ;VC erhöhen
-
- move.w LASTBKGD(a4),d0 ;Letzter Hintergrund, wenn X-Scroll>0
- move.b LASTBKGD(a4),d0
-
- move.w d0,Col40XStart(a5)
- move.w d0,Col40XStart+2(a5)
- move.w d0,Col40XStart+4(a5)
- move.w d0,Col40XStart+6(a5)
-
- ; Schleife für 40 Bytes
- moveq #39,d1 ;d1: Zeichenzähler
- BitMapLoop move.b (a2)+,d2 ;Farbe holen
- move.b d2,d3 ;d3: Hintergrundfarbe
- move.b (a0),d0 ;Byte holen
- beq BOnlyBack
- lsr.b #4,d2 ;d2: Vordergrundfarbe
-
- ; 8 Pixel konvertieren
- add.b d0,d0
- bcc 11$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 12$
- 11$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 12$ add.b d0,d0
- bcc 21$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 22$
- 21$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 22$ add.b d0,d0
- bcc 31$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 32$
- 31$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 32$ add.b d0,d0
- bcc 41$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 42$
- 41$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 42$ add.b d0,d0
- bcc 51$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 52$
- 51$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 52$ add.b d0,d0
- bcc 61$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 62$
- 61$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 62$ add.b d0,d0
- bcc 71$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 72$
- 71$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 72$ add.b d0,d0
- bcc 81$
- move.b d2,(a1)+
- IFNE SPR_DATA_COLL
- st.b (a6)+
- ENDC
- bra 82$
- 81$ move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.b (a6)+
- ENDC
- 82$ addq.l #8,a0 ;Quellzeiger erhöhen
- dbra d1,BitMapLoop
-
- move.b d3,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- BOnlyBack move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- IFNE SPR_DATA_COLL
- clr.l (a6)+
- clr.l (a6)+
- ENDC
- addq.l #8,a0 ;Quellzeiger erhöhen
- dbra d1,BitMapLoop
- move.b d3,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
- bra DoSprites
-
- *
- * Multicolor-Bitmap: Grafikdaten holen und darstellen
- *
-
- BitMapMulti move.l BITMAPBASE(a4),a0 ;a0: Bitmap-Basis
- move.w VCCOUNT(a4),d0 ;VC holen
- lsl.w #3,d0 ;*8
- add.w RC(a4),d0 ;RC dazunehmen
- add.w d0,a0 ;und zur Bitmap-Basis dazunehmen
-
- add.w #40,VCCOUNT(a4) ;VC erhöhen
-
- move.l BACK0LONG(a4),d5 ;d5.w: Farbe 0
-
- move.l d5,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
- move.l d5,Col40XStart+4(a5)
-
- ; Schleife für 40 Bytes
- moveq #39,d1
- BitMapMLoop move.b (a2)+,d2 ;Farbe 1/2 holen
- move.b (a0),d0 ;Byte holen
- beq BMOnlyBack
- move.b d2,d3 ;d3.b: Farbe 2
- lsl.w #8,d3
- move.b d2,d3
- lsr.b #4,d2 ;d2.b: Farbe 1
- move.b (a3),d4 ;d4.b: Farbe 3
- lsl.w #8,d4
- move.b (a3)+,d4
-
- ; 4 Pixel konvertieren
- add.b d0,d0
- bcc 11$
- add.b d0,d0
- bcc 12$
- move.w d4,(a1)+ ;11
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 14$
- 12$ move.w d3,(a1)+ ;10
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 14$
- 11$
- IFNE SPR_DATA_COLL
- clr.w (a6)+
- ENDC
- add.b d0,d0
- bcc 13$
- move.b d2,(a1)+ ;01
- move.b d2,(a1)+
- bra 14$
- 13$ move.w d5,(a1)+ ;00
- 14$
-
- add.b d0,d0
- bcc 21$
- add.b d0,d0
- bcc 22$
- move.w d4,(a1)+ ;11
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 24$
- 22$ move.w d3,(a1)+ ;10
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 24$
- 21$
- IFNE SPR_DATA_COLL
- clr.w (a6)+
- ENDC
- add.b d0,d0
- bcc 23$
- move.b d2,(a1)+ ;01
- move.b d2,(a1)+
- bra 24$
- 23$ move.w d5,(a1)+ ;00
- 24$
-
- add.b d0,d0
- bcc 31$
- add.b d0,d0
- bcc 32$
- move.w d4,(a1)+ ;11
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 34$
- 32$ move.w d3,(a1)+ ;10
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 34$
- 31$
- IFNE SPR_DATA_COLL
- clr.w (a6)+
- ENDC
- add.b d0,d0
- bcc 33$
- move.b d2,(a1)+ ;01
- move.b d2,(a1)+
- bra 34$
- 33$ move.w d5,(a1)+ ;00
- 34$
-
- add.b d0,d0
- bcc 41$
- add.b d0,d0
- bcc 42$
- move.w d4,(a1)+ ;11
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 44$
- 42$ move.w d3,(a1)+ ;10
- IFNE SPR_DATA_COLL
- st.b (a6)+
- st.b (a6)+
- ENDC
- bra 44$
- 41$
- IFNE SPR_DATA_COLL
- clr.w (a6)+
- ENDC
- add.b d0,d0
- bcc 43$
- move.b d2,(a1)+ ;01
- move.b d2,(a1)+
- bra 44$
- 43$ move.w d5,(a1)+ ;00
- 44$
- addq.l #8,a0 ;Quellzeiger erhöhen
- dbra d1,BitMapMLoop
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- BMOnlyBack move.l d5,(a1)+
- move.l d5,(a1)+
- IFNE SPR_DATA_COLL
- clr.l (a6)+
- clr.l (a6)+
- ENDC
- addq.w #1,a3 ;Farb-RAM-Byte überspringen
- addq.l #8,a0 ;Quellzeiger erhöhen
- dbra d1,BitMapMLoop
- bra DoSprites
-
- *
- * Ungültiger Darstellungsmodus: Schwarzen Bildschirm anzeigen
- *
-
- BlackScreen add.w #40,VCCOUNT(a4) ;VC erhöhen
-
- moveq #39,d0 ;40 Zeichen schwarz
- 1$ clr.l (a1)+
- clr.l (a1)+
- IFNE SPR_DATA_COLL
- clr.l (a6)+
- clr.l (a6)+
- ENDC
- dbra d0,1$
- bra DoSprites
-
- *
- * $3FFF darstellen
- *
-
- Show3FFF move.l BACK0LONG(a4),d3 ;d3.w: Hintergrundfarbe
-
- move.l d3,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
- move.l d3,Col40XStart+4(a5)
-
- btst #6,CTRL1(a4)
- bne 11$
- move.w #$3fff,d0 ;Byte bei $3FFF lesen
- bra 12$
- 11$ move.w #$39ff,d0 ;ECM: Byte bei $39FF lesen
- 12$ bsr GetPhysical
- move.b (a0),d0 ;Byte lesen
-
- ; 4 Pixel nach d1 konvertieren, 0: Hintergrund, 1: schwarz
- moveq #0,d1
- add.b d0,d0
- bcs 1$
- move.b d3,d1
- 1$ lsl.w #8,d1
- add.b d0,d0
- bcs 2$
- move.b d3,d1
- 2$ lsl.l #8,d1
- add.b d0,d0
- bcs 3$
- move.b d3,d1
- 3$ lsl.l #8,d1
- add.b d0,d0
- bcs 4$
- move.b d3,d1
- 4$
-
- ; 4 Pixel nach d2 konvertieren
- moveq #0,d2
- add.b d0,d0
- bcs 5$
- move.b d3,d2
- 5$ lsl.w #8,d2
- add.b d0,d0
- bcs 6$
- move.b d3,d2
- 6$ lsl.l #8,d2
- add.b d0,d0
- bcs 7$
- move.b d3,d2
- 7$ lsl.l #8,d2
- add.b d0,d0
- bcs 8$
- move.b d3,d2
- 8$
-
- ; Zeile schreiben
- moveq #39,d0 ;d0: Bytezähler
- Loop3FFF move.l d1,(a1)+
- move.l d2,(a1)+
- IFNE SPR_DATA_COLL
- clr.l (a6)+ ;Falsch!!
- clr.l (a6)+
- ENDC
- dbra d0,Loop3FFF
-
- *
- * Sprites malen?
- *
-
- DoSprites tst.b SPRITEON(a4) ;Ist überhaupt ein Sprite z.Z. sichtbar?
- beq DrawLRBorder ;Nein, dann Rahmen
-
- *
- * Mindestens ein Sprite ist sichtbar, Sprites malen
- *
-
- ; Kollisions-Puffer löschen
- lea SprCollBuf,a0
- moveq #DisplayX/4-1,d0
- 1$ clr.l (a0)+
- dbra d0,1$
-
- ; Sprites malen
- moveq #0,d4 ;Sprite-Grafik Kollisionsflag
- moveq #0,d5 ;Sprite-Sprite Kollisionsflag
- DoSprite 0
- DoSprite 1
- DoSprite 2
- DoSprite 3
- DoSprite 4
- DoSprite 5
- DoSprite 6
- DoSprite 7
- move.w CURRENTRASTER(a4),d7 ;d7 wurde zerstört
-
- ; Kollisions-Flags auswerten
- tst.w Collisions
- beq DrawLRBorder
-
- move.b CLXSPR(a4),d0
- or.b d5,CLXSPR(a4) ;Bits im Kollisionsregister setzen
- tst.b d0 ;Haben bereits Kollisionen stattgefunden?
- bne 2$
- or.b #$04,IRQFLAG(a4) ;Nein, IMMC-Bit setzen
- btst #2,IRQMASK(a4) ;IRQ erlaubt?
- beq 2$
- or.b #$80,IRQFLAG(a4) ;Ja, IRQ-Bit setzen
- st.b IntIsVICIRQ ;Und Interrupt auslösen
-
- 2$ move.b CLXBGR(a4),d0
- or.b d4,CLXBGR(a4)
- tst.b d0
- bne DrawLRBorder
- or.b #$02,IRQFLAG(a4)
- btst #1,IRQMASK(a4)
- beq DrawLRBorder
- or.b #$80,IRQFLAG(a4)
- st.b IntIsVICIRQ
-
- *
- * Linken und rechten Rahmen zeichnen
- *
-
- ; 40-Spalten-Rahmen
- DrawLRBorder move.l a5,a0
- move.l BORDERLONG(a4),d0 ;d0.l: Rahmenfarbe
-
- move.l d0,(a0)+ ;Links: $00..$1f
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
-
- lea Col40XStop-Col40XStart(a0),a0
- move.l d0,(a0)+ ;Rechts: $160..$17f
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)
-
- ; 38-Spalten-Rahmen
- tst.b IS38COL(a4)
- beq 1$
-
- lea Col40XStart(a5),a0
- move.l d0,(a0)+ ;Links: $20..$26
- move.w d0,(a0)+
- move.b d0,(a0)
-
- lea Col38XStop(a5),a0
- move.b d0,(a0)+ ;Rechts: $157..$15e
- move.l d0,(a0)+
- move.l d0,(a0)+
- 1$ bra VICIncA5
-
- *
- * Bild wird übersprungen, nur Bad-Line-Zyklen berechnen
- *
-
- VICSkip cmp.w #FirstDMALine,d7 ;Innerhalb des DMA-Bereiches?
- blo VICNop
- cmp.w #LastDMALine,d7
- bhi VICNop
-
- move.b d7,d0 ;Ja, stimmen die unteren Bits
- and.b #7,d0 ;der Rasterzeile mit dem Y-Scroll
- cmp.b YSCROLL+1(a4),d0 ;überein?
- bne VICNop
-
- move.w BadLineCycles,CyclesLeft
- bra VICNop
-
- *
- * Bei 8 Bit eine Pixelzeile darstellen
- * Zeiger in ChunkyBuf erhöhen
- *
-
- VICIncA5 cmp.w #STYP_8BIT,ScreenType
- bne VICIncA5Really
-
- tst.b IsCyber
- beq 1$
- tst.b IsCyberDirect
- beq 2$
-
- moveq #DisplayX/4-1,d0 ;CyberDirect
- lea ChunkyBuf,a0
- move.l CyberBase,a1
- move.l a1,d1
- 3$ move.l (a0)+,(a1)+
- dbra d0,3$
- add.l CyberXMod,d1
- move.l d1,CyberBase
- bra VICIncRC
-
- 2$ move.l _CyberGfxBase,a6 ;Cyber
- lea CyberHook,a0
- move.l _the_rast_port,a1
- sub.l a2,a2
- jsr DoCDrawMethod(a6)
- bra VICIncRC
-
- 1$ move.l _GfxBase,a6 ;Normal
- move.l _the_rast_port,a0
- moveq #0,d0
- move.w CURRENTRASTER(a4),d1
- sub.w #FirstDispLine,d1
- move.l #DisplayX,d2
- lea ChunkyBuf,a2
- lea _temp_rp,a1
- JSRLIB WritePixelLine8
- bra VICIncRC
-
- CyberHookProc move.l (a1),a0 ;a0: Adresse des Bildschirmspeichers
- moveq #0,d0
- move.w 20(a1),d0
- move.w Registers+CURRENTRASTER,d1
- sub.w #FirstDispLine,d1
- mulu.w d1,d0
- add.l d0,a0
- lea ChunkyBuf,a1
- moveq #DisplayX/4-1,d0
- 1$ move.l (a1)+,(a0)+
- dbra d0,1$
- rts
-
- VICIncA5Really add.l #DisplayX,CURRENTA5(a4)
-
- *
- * RC erhöhen, Darstellung abschalten, wenn gleich 7
- * (braucht nur im sichtbaren Bereich zu geschehen)
- *
-
- VICIncRC cmp.w #7,RC(a4)
- beq 1$
- addq.w #1,RC(a4)
- bra 2$
- 1$ st.b DISPLAYOFF(a4)
- move.w VCCOUNT(a4),VCBASE(a4)
- 2$
-
- *
- * MCs erhöhen (muß in jeder Rasterzeile geschehen, damit die Sprites
- * auch im Overscan-Bereich korrekt dargestellt werden)
- *
-
- ; Wenn alle Sprites aus sind, direkt zu CIA-Periodic springen
- VICNop lea SPRITEON(a4),a3
- move.b SPREN(a4),d0
- or.b (a3),d0
- beq Periodic6526
-
- ; MC für jedes Sprite zählen (7..0)
- moveq #7,d6 ;d6: Spritenummer
- lea M7Y(a4),a1 ;a1: Zeiger auf erste Y-Koordinate
- lea MC7(a4),a2 ;a2: Zeiger auf MC
-
- MCLoop move.b (a1),d0 ;Y-Koordinate
- btst d6,SPREN(a4) ;Sprite angeschaltet?
- bne 1$
- 3$ cmp.w #60,(a2) ;Nein, MC kleiner als 60?
- blo 2$
- bclr d6,(a3) ;Nein, Sprite nicht mehr darstellen
- bra 5$
-
- 1$ cmp.b d0,d7 ;Sprite angeschaltet, Y-Koord. vergleichen
- bne 3$
- clr.w (a2) ;Gleich, MC zurücksetzen
- bset d6,(a3) ;Und Sprite ab jetzt darstellen
- bra 5$
-
- 2$ btst d6,MYE(a4) ;MC kleiner als 60, Sprite Y-expandiert?
- beq 4$
- eor.b d7,d0 ;Ja, nur erhöhen, wenn Bit 0
- and.b #$01,d0 ; der Y-Koordinate gleich Bit 0
- bne 5$ ; des Rasterzählers ist
- 4$ addq.w #3,(a2) ;MC erhöhen
- subq.w #2,CyclesLeft ;2 Zyklen vom 6510 abziehen
-
- 5$ subq.w #2,a1 ;Zeiger auf Y-Koordinate erhöhen
- subq.w #2,a2 ;Zeiger auf MC erhöhen
- dbra d6,MCLoop
-
- ; Zu CIA-Periodic springen
- bra Periodic6526
-
-
- **
- ** Ein Sprite zeichnen
- ** d0.l: Spritedaten
- ** d1.w: X-Koordinate
- ** d2.b: Spritefarbe
- ** d3 : (Temp.)
- ** d4.b: Kollisionsergebnis Sprite-Hintergrund
- ** d5.b: Kollisionsergebnis Sprite-Sprite
- ** d6 : (Pixelzähler)
- ** d7.b: Sprite-Bit (1,2,4, ...)
- ** a1 : Ziel im Bildschirmspeicher
- ** a2 : Ziel im Kollisionspuffer
- ** a3 : Zeiger auf Grafik-Kollisionspuffer
- **
-
- CNOP 0,4
- ; Standard-Sprite: 3 Byte mit je 8 Pixeln konvertieren
- DrawSprStd cmp.w #DisplayX-24,d1 ;Sprite horizontal sichtbar?
- bhs DSSRts
-
- moveq #0,d6 ;Pixelzähler
- DSSLoop add.l d0,d0 ;Pixel gesetzt?
- bcc DSSNext
-
- IFNE SPR_DATA_COLL
- tst.b (a3,d6.l) ;Ist hier schon Grafik?
- beq 1$
- or.b d7,d4 ;Ja, Kollision erkannt
- 1$
- ENDC
- move.b (a2,d6.l),d1 ;Ist schon ein Sprite da?
- bne DSSDont
-
- move.b d2,(a1,d6.l) ;Nein, Punkt setzen
- move.b d7,(a2,d6.l)
- bra DSSNext
-
- DSSDont or.b d1,d5 ;Ja, Kollision erkannt zwischen bestehendem
- or.b d7,d5 ; und aktuellem Sprite
-
- DSSNext addq.w #1,d6
- cmp.w #24,d6
- bne DSSLoop
- DSSRts rts
-
- CNOP 0,4
- ; X-expandiertes Standard-Sprite: 3 Byte mit je 8 Pixeln konvertieren
- DrawSprStdExp cmp.w #DisplayX-48,d1
- bhs DSSERts
-
- moveq #0,d6
- DSSELoop add.l d0,d0
- bcc DSSENext
-
- IFNE SPR_DATA_COLL
- tst.b (a3,d6.l)
- beq 1$
- or.b d7,d4
- 1$
- ENDC
- move.b (a2,d6.l),d1
- bne DSSEDont1st
-
- move.b d2,(a1,d6.l)
- move.b d7,(a2,d6.l)
- bra DSSETest2nd
-
- DSSEDont1st or.b d1,d5
- or.b d7,d5
-
- DSSETest2nd
- IFNE SPR_DATA_COLL
- tst.b 1(a3,d6.l)
- beq 1$
- or.b d7,d4
- 1$
- ENDC
- move.b 1(a2,d6.l),d1
- bne DSSEDont2nd
-
- move.b d2,1(a1,d6.l)
- move.b d7,1(a2,d6.l)
- bra DSSENext
-
- DSSEDont2nd or.b d1,d5
- or.b d7,d5
-
- DSSENext addq.w #2,d6
- cmp.w #48,d6
- bne DSSELoop
- DSSERts rts
-
- CNOP 0,4
- ; Multicolor-Sprite: 3 Byte mit je 4 Pixeln konvertieren
- DrawSprMulti cmp.w #DisplayX-24,d1
- bhs DSMRts
-
- moveq #0,d6
- DSMLoop add.l d0,d0 ;Farbe des Pixels bestimmen
- bcc DSMFirstIs0
- add.l d0,d0
- bcc DSMDraw10
- move.b $26(a4),d3 ;11
- bra DSMDraw
- DSMDraw10 move.b d2,d3 ;10
- bra DSMDraw
- DSMFirstIs0 add.l d0,d0
- bcc DSMNext
- move.b $25(a4),d3 ;01
-
- DSMDraw
- IFNE SPR_DATA_COLL
- tst.b (a3,d6.l)
- beq 1$
- or.b d7,d4
- 1$
- ENDC
- move.b (a2,d6.l),d1
- bne DSMDont1st
-
- move.b d3,(a1,d6.l)
- move.b d7,(a2,d6.l)
- bra DSMTest2nd
-
- DSMDont1st or.b d1,d5
- or.b d7,d5
-
- DSMTest2nd
- IFNE SPR_DATA_COLL
- tst.b 1(a3,d6.l)
- beq 1$
- or.b d7,d4
- 1$
- ENDC
- move.b 1(a2,d6.l),d1
- bne DSMDont2nd
-
- move.b d3,1(a1,d6.l)
- move.b d7,1(a2,d6.l)
- bra DSMNext
-
- DSMDont2nd or.b d1,d5
- or.b d7,d5
-
- DSMNext addq.w #2,d6
- cmp.w #24,d6
- bne DSMLoop
- DSMRts rts
-
- CNOP 0,4
- ; X-expandiertes Multicolor-Sprite: 3 Byte mit je 4 Pixeln konvertieren
- DrawSprMultiExp cmp.w #DisplayX-48,d1
- bhs DSMERts
-
- moveq #0,d6
- DSMELoop add.l d0,d0
- bcc DSMEFirstIs0
- add.l d0,d0
- bcc DSMEDraw10
- move.b $26(a4),d3 ;11
- bra DSMEDraw
- DSMEDraw10 move.b d2,d3 ;10
- bra DSMEDraw
- DSMEFirstIs0 add.l d0,d0
- bcc DSMENext
- move.b $25(a4),d3 ;01
-
- DSMEDraw
- IFNE SPR_DATA_COLL
- tst.b (a3,d6.l)
- beq 1$
- or.b d7,d4
- 1$
- ENDC
- move.b (a2,d6.l),d1
- bne DSMEDont1st
-
- move.b d3,(a1,d6.l)
- move.b d7,(a2,d6.l)
- bra DSMETest2nd
-
- DSMEDont1st or.b d1,d5
- or.b d7,d5
-
- DSMETest2nd
- IFNE SPR_DATA_COLL
- tst.b 1(a3,d6.l)
- beq 1$
- or.b d7,d4
- 1$
- ENDC
- move.b 1(a2,d6.l),d1
- bne DSMEDont2nd
-
- move.b d3,1(a1,d6.l)
- move.b d7,1(a2,d6.l)
- bra DSMETest3rd
-
- DSMEDont2nd or.b d1,d5
- or.b d7,d5
-
- DSMETest3rd
- IFNE SPR_DATA_COLL
- tst.b 2(a3,d6.l)
- beq 1$
- or.b d7,d4
- 1$
- ENDC
- move.b 2(a2,d6.l),d1
- bne DSMEDont3rd
-
- move.b d3,2(a1,d6.l)
- move.b d7,2(a2,d6.l)
- bra DSMETest4th
-
- DSMEDont3rd or.b d1,d5
- or.b d7,d5
-
- DSMETest4th
- IFNE SPR_DATA_COLL
- tst.b 3(a3,d6.l)
- beq 1$
- or.b d7,d4
- 1$
- ENDC
- move.b 3(a2,d6.l),d1
- bne DSMEDont4th
-
- move.b d3,3(a1,d6.l)
- move.b d7,3(a2,d6.l)
- bra DSMENext
-
- DSMEDont4th or.b d1,d5
- or.b d7,d5
-
- DSMENext addq.w #4,d6
- cmp.w #48,d6
- bne DSMELoop
- DSMERts rts
-
- CNOP 0,4
- ; Standard-Sprite im Hintergrund: 3 Byte mit je 8 Pixeln konvertieren
- DrawBackStd cmp.w #DisplayX-24,d1 ;Sprite horizontal sichtbar?
- bhs DBSRts
-
- moveq #0,d6 ;Pixelzähler
- DBSLoop add.l d0,d0 ;Pixel gesetzt?
- bcc DBSNext
-
- IFNE SPR_DATA_COLL
- tst.b (a3,d6.l) ;Ist hier schon Grafik?
- beq 1$
- or.b d7,d4 ;Ja, Kollision erkannt
- move.b (a2,d6.l),d1 ;Ist schon ein Sprite da?
- beq DBSNext
- or.b d1,d5 ;Ja, Kollision erkannt
- or.b d7,d5
- bra DBSNext ;Sprite nicht zeichnen
- 1$
- ENDC
- move.b (a2,d6.l),d1 ;Ja, ist schon ein Sprite da?
- bne DBSDont
-
- move.b d2,(a1,d6.l) ;Nein, Punkt setzen
- move.b d7,(a2,d6.l)
- bra DBSNext
-
- DBSDont or.b d1,d5 ;Ja, Kollision erkannt zwischen bestehendem
- or.b d7,d5 ; und aktuellem Sprite
-
- DBSNext addq.w #1,d6
- cmp.w #24,d6
- bne DBSLoop
- DBSRts rts
-
- CNOP 0,4
- ; X-expandiertes Standard-Sprite im Hintergrund: 3 Byte mit je 8 Pixeln konvertieren
- DrawBackStdExp cmp.w #DisplayX-48,d1
- bhs DBSERts
-
- moveq #0,d6
- DBSELoop add.l d0,d0
- bcc DBSENext
-
- IFNE SPR_DATA_COLL
- tst.b (a3,d6.l)
- beq 1$
- or.b d7,d4
- move.b (a2,d6.l),d1
- beq DBSETest2nd
- or.b d1,d5
- or.b d7,d5
- bra DBSETest2nd
- 1$
- ENDC
- move.b (a2,d6.l),d1
- bne DBSEDont1st
-
- move.b d2,(a1,d6.l)
- move.b d7,(a2,d6.l)
- bra DBSETest2nd
-
- DBSEDont1st or.b d1,d5
- or.b d7,d5
-
- DBSETest2nd
- IFNE SPR_DATA_COLL
- tst.b 1(a3,d6.l)
- beq 1$
- or.b d7,d4
- move.b 1(a2,d6.l),d1
- beq DBSENext
- or.b d1,d5
- or.b d7,d5
- bra DBSENext
- 1$
- ENDC
- move.b 1(a2,d6.l),d1
- bne DBSEDont2nd
-
- move.b d2,1(a1,d6.l)
- move.b d7,1(a2,d6.l)
- bra DBSENext
-
- DBSEDont2nd or.b d1,d5
- or.b d7,d5
-
- DBSENext addq.w #2,d6
- cmp.w #48,d6
- bne DBSELoop
- DBSERts rts
-
- CNOP 0,4
- ; Multicolor-Sprite im Hintergrund: 3 Byte mit je 4 Pixeln konvertieren
- DrawBackMulti cmp.w #DisplayX-24,d1
- bhs DBMRts
-
- moveq #0,d6
- DBMLoop add.l d0,d0 ;Farbe des Pixels bestimmen
- bcc DBMFirstIs0
- add.l d0,d0
- bcc DBMDraw10
- move.b $26(a4),d3 ;11
- bra DBMDraw
- DBMDraw10 move.b d2,d3 ;10
- bra DBMDraw
- DBMFirstIs0 add.l d0,d0
- bcc DBMNext
- move.b $25(a4),d3 ;01
-
- DBMDraw
- IFNE SPR_DATA_COLL
- tst.b (a3,d6.l)
- beq 1$
- or.b d7,d4
- move.b (a2,d6.l),d1
- beq DBMTest2nd
- or.b d1,d5
- or.b d7,d5
- bra DBMTest2nd
- 1$
- ENDC
- move.b (a2,d6.l),d1
- bne DBMDont1st
-
- move.b d3,(a1,d6.l)
- move.b d7,(a2,d6.l)
- bra DBMTest2nd
-
- DBMDont1st or.b d1,d5
- or.b d7,d5
-
- DBMTest2nd
- IFNE SPR_DATA_COLL
- tst.b 1(a3,d6.l)
- beq 1$
- or.b d7,d4
- move.b 1(a2,d6.l),d1
- beq DBMNext
- or.b d1,d5
- or.b d7,d5
- bra DBMNext
- 1$
- ENDC
- move.b 1(a2,d6.l),d1
- bne DBMDont2nd
-
- move.b d3,1(a1,d6.l)
- move.b d7,1(a2,d6.l)
- bra DBMNext
-
- DBMDont2nd or.b d1,d5
- or.b d7,d5
-
- DBMNext addq.w #2,d6
- cmp.w #24,d6
- bne DBMLoop
- DBMRts rts
-
- CNOP 0,4
- ; X-expandiertes Multicolor-Sprite im Hintergrund: 3 Byte mit je 4 Pixeln konvertieren
- DrawBackMultiExp cmp.w #DisplayX-48,d1
- bhs DBMERts
-
- moveq #0,d6
- DBMELoop add.l d0,d0
- bcc DBMEFirstIs0
- add.l d0,d0
- bcc DBMEDraw10
- move.b $26(a4),d3 ;11
- bra DBMEDraw
- DBMEDraw10 move.b d2,d3 ;10
- bra DBMEDraw
- DBMEFirstIs0 add.l d0,d0
- bcc DBMENext
- move.b $25(a4),d3 ;01
-
- DBMEDraw
- IFNE SPR_DATA_COLL
- tst.b (a3,d6.l)
- beq 1$
- or.b d7,d4
- move.b (a2,d6.l),d1
- beq DBMETest2nd
- or.b d1,d5
- or.b d7,d5
- bra DBMETest2nd
- 1$
- ENDC
- move.b (a2,d6.l),d1
- bne DBMEDont1st
-
- move.b d3,(a1,d6.l)
- move.b d7,(a2,d6.l)
- bra DBMETest2nd
-
- DBMEDont1st or.b d1,d5
- or.b d7,d5
-
- DBMETest2nd
- IFNE SPR_DATA_COLL
- tst.b 1(a3,d6.l)
- beq 1$
- or.b d7,d4
- move.b 1(a2,d6.l),d1
- beq DBMETest3rd
- or.b d1,d5
- or.b d7,d5
- bra DBMETest3rd
- 1$
- ENDC
- move.b 1(a2,d6.l),d1
- bne DBMEDont2nd
-
- move.b d3,1(a1,d6.l)
- move.b d7,1(a2,d6.l)
- bra DBMETest3rd
-
- DBMEDont2nd or.b d1,d5
- or.b d7,d5
-
- DBMETest3rd
- IFNE SPR_DATA_COLL
- tst.b 2(a3,d6.l)
- beq 1$
- or.b d7,d4
- move.b 2(a2,d6.l),d1
- beq DBMETest4th
- or.b d1,d5
- or.b d7,d5
- bra DBMETest4th
- 1$
- ENDC
- move.b 2(a2,d6.l),d1
- bne DBMEDont3rd
-
- move.b d3,2(a1,d6.l)
- move.b d7,2(a2,d6.l)
- bra DBMETest4th
-
- DBMEDont3rd or.b d1,d5
- or.b d7,d5
-
- DBMETest4th
- IFNE SPR_DATA_COLL
- tst.b 3(a3,d6.l)
- beq 1$
- or.b d7,d4
- move.b 3(a2,d6.l),d1
- beq DBMENext
- or.b d1,d5
- or.b d7,d5
- bra DBMENext
- 1$
- ENDC
- move.b 3(a2,d6.l),d1
- bne DBMEDont4th
-
- move.b d3,3(a1,d6.l)
- move.b d7,3(a2,d6.l)
- bra DBMENext
-
- DBMEDont4th or.b d1,d5
- or.b d7,d5
-
- DBMENext addq.w #4,d6
- cmp.w #48,d6
- bne DBMELoop
- DBMERts rts
-
-
- **
- ** Amiga-Mono-Routinen einbinden
- **
-
- INCLUDE "6569mono.i"
-
-
- **
- ** Konstanten
- **
-
- ; Tabelle der Display-Routinen (jeweils für Farbe und Monochrom)
- CNOP 0,4
- DispProcTab dc.l TextStd
- dc.l TextMulti
- dc.l BitMapStd
- dc.l BitMapMulti
- dc.l TextECM
- dc.l BlackScreen
- dc.l BlackScreen
- dc.l BlackScreen
-
- MonoDispProcTab dc.l FTextStd
- dc.l FTextStd
- dc.l FBitMapStd
- dc.l FBitMapStd
- dc.l FTextStd
- dc.l FBlackScreen
- dc.l FBlackScreen
- dc.l FBlackScreen
-
- ; Tabelle der Sprite-Display-Routinen
- SpriteProcTab dc.l DrawSprStd
- dc.l DrawSprStdExp
- dc.l DrawSprMulti
- dc.l DrawSprMultiExp
- dc.l DrawBackStd
- dc.l DrawBackStdExp
- dc.l DrawBackMulti
- dc.l DrawBackMultiExp
-
- ; Hook für DoCDrawMethod
- CyberHook dc.l 0,0
- dc.l CyberHookProc
- dc.l 0
- dc.l 0
-
-
- **
- ** Datenbereich
- **
-
- ; Variablen
- CNOP 0,4
- DisplayProc dc.l 0 ;Zeiger auf die Display-Routine (Text/Bitmap etc.)
-
- Sprite0Proc dc.l 0 ;Zeiger auf Display-Routinen für die einzelnen Sprites
- Sprite1Proc dc.l 0
- Sprite2Proc dc.l 0
- Sprite3Proc dc.l 0
- Sprite4Proc dc.l 0
- Sprite5Proc dc.l 0
- Sprite6Proc dc.l 0
- Sprite7Proc dc.l 0
-
- DisplayID dc.l 0 ;Prefs: DisplayID des Screens
- ScreenType dc.w 0 ;Prefs: Typ der Screen-Ansteuerung
- NormalCycles dc.w 0 ;Prefs: Anzahl 6510-Zyklen pro Rasterzeile
- BadLineCycles dc.w 0 ;Prefs: Anzahl 6510-Zyklen in einer Bad Line
- Collisions dc.w 0 ;Prefs: Sprite-Kollisionen angeschaltet
- Overscan dc.w 0 ;Prefs: Overscan-Typ für Amiga-Modi
- DirectVideo dc.w 0 ;Prefs: Direkter Grafikspeicherzugriff bei 8 Bit erlaubt
-
- SkipCounter dc.w 1
- XDEF _SkipLatch
- _SkipLatch
- SkipLatch dc.w 0 ;Prefs: Nur jedes nte Bild darstellen
-
- XDEF _LimitSpeed
- _LimitSpeed
- LimitSpeed dc.w 0 ;Prefs: Geschwindigkeit auf 100% beschränken
-
- IsCyber dc.b 0 ;#0: DoCDrawMethod kann statt WritePixelLine8 benutzt werden
- IsCyberDirect dc.b 0 ;#0: Direkter Bildschirmspeicherzugriff erlaubt
- CNOP 0,4
- CyberBase dc.l 0 ;Basisadresse des Bildschirmspeichers
- CyberXMod dc.l 0 ;Modulo des Bildschirmspeichers
-
- CNOP 0,4
- Registers ds.b VICRegLength ;VIC-Register
- MatrixLine ds.b 40 ;Eine Bildschirmzeile
- ColorLine ds.b 40 ;Eine Farb-RAM-Zeile
-
-
- **
- ** Nicht initialisierte Daten
- **
-
- SECTION "BSS",BSS
- XDEF _ChunkyBuf
- _ChunkyBuf
- ChunkyBuf ds.b DisplayX*DisplayY ;Puffer für die Chunky-Bitmap
-
- SprCollBuf ds.b DisplayX ;Puffer für Sprite-Sprite-Kollisionen
- IFNE SPR_DATA_COLL
- GfxCollBuf ds.b DisplayX ;Puffer für Sprite-Grafik-Kollisionen und Priorität
- ENDC
-
- XDEF _CURRENTA5
- _CURRENTA5 ds.l 1 ;Kommunikation mit _RedrawDisplay
-
- END
-